package rpcbiz

import (
	"errors"
	"net"
	"fmt"
	"github.com/astaxie/beego/logs"
	"cloud_worm/util/proto/urpc"
	"cloud_worm/util/unet/rpc"
	"cloud_worm/util/uconst"
	"cloud_worm/util/proto/ujson"
	"strings"
	"cloud_worm/wormweb/controllers/ctrutil"
)

type PushMsgArgs urpc.PushMsgArgs

func (args *PushMsgArgs) param() error {
	if len(args.AgentId) != uconst.AgentIdLen {
		return errors.New("agent id error")
	}
	if net.ParseIP(args.AgentIP) == nil {
		return errors.New("agent ip error")
	}

	return nil
}

func (w *PushMsg) MsgPost(args *PushMsgArgs, reply *urpc.PushMsgReply) error {
	if err := args.param(); err != nil {
		logs.Error(fmt.Sprintf("rpc request MsgPost error: %s", err.Error()))
		return err
	}

	msg := ujson.PushMsg{}
	if err := msg.UnmarshalJSON(args.PayLoad); err != nil {
		logs.Error(fmt.Sprintf("rpc request MsgPost unmarshalJSON error: %s", err.Error()))
		return nil
	}

	switch msg.Type {
	case ujson.PushErrMsg:
		errMsg := ujson.ErrMsg{}
		if err := errMsg.UnmarshalJSON(msg.Payload); err != nil {
			logs.Error(fmt.Sprintf("rpc request MsgPost's ErrMsg unmarshalJSON error: %s", err.Error()))
			return nil
		}

		notice := fmt.Sprintf("%s %s: %s", args.TimeStamp, args.AgentIP, errMsg.Err)
		logs.Error(notice)
		// TODO: 推送信息处理


	case ujson.PushStatMsg:
		statMsg := ujson.StatInfo{}
		if err := statMsg.UnmarshalJSON(msg.Payload); err != nil {
			logs.Error(fmt.Sprintf("rpc request MsgPost's StatInfo unmarshalJSON error: %s", err.Error()))
			return nil
		}
		w.dealStatInfo(&statMsg, args)

	default:
		logs.Error(fmt.Sprintf("rpc request MsgPost msg type unknown"))
		return nil
	}

	return nil
}

func (w *PushMsg) dealStatInfo(statMsg *ujson.StatInfo, args *PushMsgArgs)  {
	runMode := ctrutil.RunMode

	if strings.HasPrefix(runMode, uconst.RunModeDev) {
		var varSize string
		if statMsg.VarDirSize > 1024 * 1024 * 1024 {
			varSize = fmt.Sprintf("%d Gb", statMsg.VarDirSize / (1024 * 1024 * 1024))
		} else if statMsg.VarDirSize > 1024 * 1024 {
			varSize = fmt.Sprintf("%d Mb", statMsg.VarDirSize / (1024 * 1024))
		} else if statMsg.VarDirSize > 1024 {
			varSize = fmt.Sprintf("%d Kb", statMsg.VarDirSize / 1024)
		}
		msg := fmt.Sprintf("(%s)%s: NumGoroutine--%d, SysMem--%d Mb, varSize: %s",
			args.TimeStamp, args.AgentIP, statMsg.NumGo, statMsg.MemSys / 1024, varSize)
		logs.Debug(msg)
	} else {
		notifyStat := false
		// 内存超过60M，磁盘超过6G
		if statMsg.MemSys > 102400 || statMsg.VarDirSize > 6 *1024 * 1024 * 1024 {
			notifyStat = true
		}

		if notifyStat == true {
			var varSize string
			if statMsg.VarDirSize > 1024 * 1024 * 1024 {
				varSize = fmt.Sprintf("%d Gb", statMsg.VarDirSize / (1024 * 1024 * 1024))
			} else if statMsg.VarDirSize > 1024 * 1024 {
				varSize = fmt.Sprintf("%d Mb", statMsg.VarDirSize / (1024 * 1024))
			} else if statMsg.VarDirSize > 1024 {
				varSize = fmt.Sprintf("%d Kb", statMsg.VarDirSize / 1024)
			}
			msg := fmt.Sprintf("*** (%s)%s: NumGoroutine--%d, SysMem--%d Mb, varSize: %s",
				args.TimeStamp, args.AgentIP, statMsg.NumGo, statMsg.MemSys / 1024, varSize)
			logs.Warn(msg)

			// TODO: 推送通知处理

			// TODO: 其他操作
		}
	}
}

type PushMsg int

func init()  {
	rpc.Register(new(PushMsg))
}